﻿using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;

namespace Infrastructure.Base.Utils
{
    public class EncryptUtil
    {
        #region 对称加密

        private static string _encryptKey = "Peng_Yuan_key";
        private static string _encryptIv = "Pengyuan_Database";

        /// <summary>
        ///     加密
        /// </summary>
        /// <param name="encryptoContext"></param>
        /// <returns></returns>
        public static string EncryptDES(string encryptoContext)
        {
            //取 8 位 key
            string cryptoKey = _encryptKey;
            cryptoKey = cryptoKey.PadLeft(8, '0').Substring(0, 8);
            //设置加密的 key，其值来自参数
            byte[] key = Encoding.UTF8.GetBytes(cryptoKey);
            //设置加密的 iv 向量，这里使用硬编码演示
            byte[] iv = Encoding.UTF8.GetBytes(_encryptIv);
            //将需要加密的正文放进 byte 数组
            byte[] context = Encoding.UTF8.GetBytes(encryptoContext);

            var des = new DESCryptoServiceProvider();
            //创建内存流，用于取加密后的结果
            var ms = new MemoryStream();
            //创建加密流，创建加密使用 des.CreateEncryptor
            var cs = new CryptoStream(ms, des.CreateEncryptor(key, iv), CryptoStreamMode.Write);

            //向加密流写入正文
            cs.Write(context, 0, context.Length);
            //将缓冲区数据写入，然后清空缓冲区
            cs.FlushFinalBlock();

            //从内存流返回结果，并编码为 base64string 
            return Convert.ToBase64String(ms.ToArray());
        }

        /// <summary>
        ///     解密
        /// </summary>
        /// <param name="decryptoContext"></param>
        /// <returns></returns>
        public static string DecryptDES(string decryptoContext)
        {
            //取 8 位 key
            string cryptoKey = _encryptKey;
            cryptoKey = cryptoKey.PadLeft(8, '0').Substring(0, 8);
            //设置解密的 key，其值来自参数
            byte[] key = Encoding.UTF8.GetBytes(cryptoKey);
            //设置解密的 iv 向量，这里使用硬编码演示
            byte[] iv = Encoding.UTF8.GetBytes(_encryptIv);
            //将解密正文返回到 byte 数组，加密时编码为 base64string ，这里要使用 FromBase64String 直接取回 byte 数组
            byte[] context = Convert.FromBase64String(decryptoContext);

            var des = new DESCryptoServiceProvider();
            //创建内存流，用于取解密结果
            var ms = new MemoryStream();
            //创建解密的流， 这里的是 des.CreateDecryptor 
            var cs = new CryptoStream(ms, des.CreateDecryptor(key, iv), CryptoStreamMode.Write);

            //向解密流写入数据
            cs.Write(context, 0, context.Length);
            //将当前缓冲区写入绑定的内存流，然后清空缓冲区
            cs.FlushFinalBlock();

            //从内存流返回值，并编码到 UTF8 输出原文
            return Encoding.UTF8.GetString(ms.ToArray());
        }


        /// <summary>
        ///     自定key 和iv
        /// </summary>
        /// <param name="encryptoContext"></param>
        /// <param name="encryptKey"></param>
        /// <param name="encryptIv"></param>
        /// <returns></returns>
        public static string EncryptDES(string encryptoContext, string encryptKey, string encryptIv)
        {
            //取 8 位 key
            string cryptoKey = encryptKey;
            cryptoKey = cryptoKey.PadLeft(8, '0').Substring(0, 8);
            //设置加密的 key，其值来自参数
            byte[] key = Encoding.UTF8.GetBytes(cryptoKey);
            //设置加密的 iv 向量，这里使用硬编码演示
            byte[] iv = Encoding.UTF8.GetBytes(encryptIv);
            //将需要加密的正文放进 byte 数组
            byte[] context = Encoding.UTF8.GetBytes(encryptoContext);

            var des = new DESCryptoServiceProvider();
            //创建内存流，用于取加密后的结果
            var ms = new MemoryStream();
            //创建加密流，创建加密使用 des.CreateEncryptor
            var cs = new CryptoStream(ms, des.CreateEncryptor(key, iv), CryptoStreamMode.Write);

            //向加密流写入正文
            cs.Write(context, 0, context.Length);
            //将缓冲区数据写入，然后清空缓冲区
            cs.FlushFinalBlock();

            //从内存流返回结果，并编码为 base64string 
            return Convert.ToBase64String(ms.ToArray());
        }

        /// <summary>
        ///     自定key 和iv
        /// </summary>
        /// <param name="decryptoContext"></param>
        /// <param name="encryptKey"></param>
        /// <param name="encryptIv"></param>
        /// <returns></returns>
        public static string DecryptDES(string decryptoContext, string encryptKey, string encryptIv)
        {
            //取 8 位 key
            string cryptoKey = encryptKey;
            cryptoKey = cryptoKey.PadLeft(8, '0').Substring(0, 8);
            //设置解密的 key，其值来自参数
            byte[] key = Encoding.UTF8.GetBytes(cryptoKey);
            //设置解密的 iv 向量，这里使用硬编码演示
            byte[] iv = Encoding.UTF8.GetBytes(encryptIv);
            //将解密正文返回到 byte 数组，加密时编码为 base64string ，这里要使用 FromBase64String 直接取回 byte 数组
            byte[] context = Convert.FromBase64String(decryptoContext);

            var des = new DESCryptoServiceProvider();
            //创建内存流，用于取解密结果
            var ms = new MemoryStream();
            //创建解密的流， 这里的是 des.CreateDecryptor 
            var cs = new CryptoStream(ms, des.CreateDecryptor(key, iv), CryptoStreamMode.Write);

            //向解密流写入数据
            cs.Write(context, 0, context.Length);
            //将当前缓冲区写入绑定的内存流，然后清空缓冲区
            cs.FlushFinalBlock();

            //从内存流返回值，并编码到 UTF8 输出原文
            return Encoding.UTF8.GetString(ms.ToArray());
        }

        #endregion
    }
}